package com.wpi.smarttour.helpers;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

/*
 * This class helps upload files to the server
 */
public class SmartUploader implements Runnable
{
   URL connectURL;
   String responseString;
   String fileName;
   byte[] dataToServer;
   FileInputStream fileInputStream = null;

   public SmartUploader(String urlString)
   {
      Utilities.LogDebug("SmartUploader", "SmartUploader Variable Created");
      try
      {
         connectURL = new URL(urlString);
      }
      catch (Exception ex)
      {
         Utilities.LogDebug("URL FORMATION: MALFORMATED URL");
      }
   }

   public SmartUploader(String urlString, String fileName)
   {
      try
      {
         connectURL = new URL(urlString);
      }
      catch (Exception ex)
      {
         Utilities.LogDebug("URL FORMATION: MALFORMATED URL");
      }
      setFileName(fileName);
   }

   public void setFileName(String fileName)
   {
      this.fileName = fileName;
      Utilities.LogDebug("SmartUploader", "FileName Set to " + fileName);
   }

   public String getFileName()
   {
      return this.fileName;
   }

   public void doStart()
   {
      try
      {
         fileInputStream = new FileInputStream(new File(fileName));
      }
      catch (FileNotFoundException e)
      {
         Utilities.LogDebug("File Not found");
         e.printStackTrace();
      }
      doUpload();
   }

   /*
    * public void doStart(FileInputStream stream){ fileInputStream = stream;
    * doUpload(); }
    */
   // The the upload
   void doUpload()
   {
      String lineEnd = "\r\n";
      String twoHyphens = "--";
      String boundary = "*****";
      try
      {
         // ------------------ CLIENT REQUEST
         Utilities.LogDebug("Opening a HTTP connection to the URL");
         // Open a HTTP connection to the URL
         HttpURLConnection conn = (HttpURLConnection) connectURL.openConnection();
         // Allow Inputs
         conn.setDoInput(true);
         // Allow Outputs
         conn.setDoOutput(true);
         // Don't use a cached copy.
         conn.setUseCaches(false);
         // Use a post method.
         conn.setRequestMethod("POST");
         conn.setRequestProperty("Connection", "Keep-Alive");
         conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
         DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
         dos.writeBytes(twoHyphens + boundary + lineEnd);
         dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + fileName + "\"" + lineEnd);
         dos.writeBytes(lineEnd);
         Utilities.LogDebug("Headers are written");
         // create a buffer of maximum size
         int bytesAvailable = fileInputStream.available();
         int maxBufferSize = 1024;
         int bufferSize = Math.min(bytesAvailable, maxBufferSize);
         byte[] buffer = new byte[bufferSize];
         // read file and write it into form...
         int bytesRead = fileInputStream.read(buffer, 0, bufferSize);
         while(bytesRead > 0)
         {
            dos.write(buffer, 0, bufferSize);
            bytesAvailable = fileInputStream.available();
            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);
         }
         // send multipart form data necesssary after file data...
         dos.writeBytes(lineEnd);
         dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
         // close streams
         Utilities.LogDebug("File is written");
         fileInputStream.close();
         dos.flush();
         InputStream is = conn.getInputStream();
         // retrieve the response from server
         int ch;
         StringBuffer b = new StringBuffer();
         while((ch = is.read()) != -1)
         {
            b.append((char) ch);
         }
         String s = b.toString();
         Utilities.LogDebug("Response: " + s);
         dos.close();
      }
      catch (MalformedURLException ex)
      {
         Utilities.LogError("Malformed URL exception: +", ex);
      }
      catch (IOException ioe)
      {
         Utilities.LogError("Malformed IO exception: +", ioe);
      }
   }

   @Override
   public void run()
   {
      // TODO Auto-generated method stub
   }
}
